import 'package:family_expense/features/bank_card/models/bank_card.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

class BankCardService {
  final String _url = '/bank-card';
  final String _bankCardsSharingKey = 'bankCards';
  final HttpRequestService _httpRequestService = HttpRequestService();

  List<BankCard>? get currentBankCards {
    return DataSharing.get<List<BankCard>>(_bankCardsSharingKey);
  }

  /// Loads bank cards and caches it for performance concern.
  ///
  /// [loadedBankCards] is the data provided by other service. If this is not null then we don't have to load it again from server.
  Future<void> init({List<BankCard>? loadedBankCards}) async {
    // Loads the data from server if [loadedBankCards] is null.
    var bankCards =
        loadedBankCards ?? await queryAllWithBasicInfoByAccountGroup();

    // Caches the data.
    DataSharing.set<List<BankCard>>(_bankCardsSharingKey, bankCards);
  }

  // Removes the [BankCard] from cache by its [id].
  void removeFromCache(String id) {
    currentBankCards!.removeWhere((p) => p.id == id);
  }

  /// Clears the cache data.
  void clearCache() {
    DataSharing.remove(key: _bankCardsSharingKey);
  }

  /// Clears the cached bank cards and init the data again.
  Future<void> reInit({List<BankCard>? loadedBankCards}) async {
    clearCache();
    await init(loadedBankCards: loadedBankCards);
  }

  /// Retrieves all [BankCard]s from backend service.
  Future<List<BankCard>> queryAllWithBasicInfoByAccountGroup() async {
    // Gets the response of the http get request.
    final response = await _httpRequestService
        .get('$_url/query-all-with-basic-info-by-account-group');

    // Parses the data from [Map<String, dynamic>] to [BankCard].
    return (response.payload as List<dynamic>)
        .map((p) => BankCard.fromJson(p))
        .toList();
  }

  /// Retrieves the [BankCard] basic info from backend service with [id].
  Future<BankCard> queryBankCardInfo(String id) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService
        .get('$_url/query-bank-card-info', params: {'id': id});

    // Parses the data from [Map<String, dynamic>] to [BankCard].
    return BankCard.fromJson(response.payload);
  }

  /// Retrieves current user account group [BankCard] list from backend service.
  Future<List<BankCard>> queryBasicInfoByAccountGroup(
      int pageSize, int pageIndex) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
        '$_url/query-basic-info-by-account-group',
        params: {'pageSize': pageSize, 'pageIndex': pageIndex});

    // Parses the data from [Map<String, dynamic>] to [BankCard].
    final result = (response.payload as List<dynamic>)
        .map((p) => BankCard.fromJson(p))
        .toList();

    // Updates local cache just in case other users make updates.
    await reInit();

    return result;
  }

  /// Adds the new [BankCard] to server.
  Future<bool> add(BankCard bankCard) async {
    final response = await _httpRequestService.post(
      '$_url/add',
      body: bankCard.toJson(),
    );

    return response.success;
  }

  /// Updates the [BankCard] info.
  Future<void> update(BankCard bankCard) async {
    await _httpRequestService.post('$_url/update', body: bankCard.toJson());

//    // Gets the index of the matched bank card in the list via its id.
//    final matchedIndex = currentBankCards.indexWhere((p) => p.id == bankCard.id);
//
//    // Replaced with updated bank card.
//    currentBankCards[matchedIndex] = bankCard.clone();
  }

  /// Deletes bank card with [id] and removes it from cache.
  Future<bool> delete(String id) async {
    // Deletes data from server.
    final response =
        await _httpRequestService.post('$_url/delete', body: {'id': id});

    // Checks on result.
    final success = response.payload as bool;

    // If it's done then remove the data from cache.
    if (success) {
      removeFromCache(id);
    }

    return success;
  }

  /// Deletes bank card with id list.
  Future<void> batchDelete(List<String> ids) async {
    await _httpRequestService.post('$_url/batch-delete', body: {'ids': ids});
  }
}
